package com.plasticcode.performance;

import java.util.concurrent.TimeUnit;

import com.plasticcode.stats.DurationMeasurement;
import com.plasticcode.stats.SimpleTimeMeasurementRecorder;
import com.plasticcode.stats.TimeMeasurementRecorder;

public class PerformanceController {
    static final int WARM_UP_REPS = 50;
    static final int MAX_CHILDREN = 100;
    static final int CHILDREN_STEP = 5;
    static final int SAMPLES = 500;    
    
    private TimeMeasurementRecorder measurementRecorder;
    private MeasuredOperation operation;
    
    public PerformanceController(String testDescription, MeasuredOperation operation) {
        measurementRecorder = new SimpleTimeMeasurementRecorder(testDescription);
        this.operation = operation;
    }
    
    public void measure() throws Exception {
        measure(SAMPLES);
    }
    
    public void measure(int samples) throws Exception {
        
        // Warm-up before making measurements
        operation.setup(1);
        operation.run(1, WARM_UP_REPS);
        
        // Measure the performance against the number of runs inserted
        for (int children = 1; children <= MAX_CHILDREN; children += CHILDREN_STEP) {
            operation.setup(children);
            
            DurationMeasurement duration = new DurationMeasurement(TimeUnit.MILLISECONDS, samples);
            duration.startMeasurement();
            
            operation.run(children, samples);

            duration.endMeasurement();
            measurementRecorder.record(String.valueOf(children), duration); 
        }
    }
}
